package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"gitee.com/huyi1199/common/lib"

	"gorm.io/gorm"

	"github.com/go-redis/redis/v8"
)

var traceCtx = context.Background()

func main() {
	lib.Log.TagInfo(lib.NewTraceInfo(), lib.DLTagUndefind, map[string]interface{}{"message": "todo sth"})

	if err := lib.InitModule("./conf/dev/", []string{"base", "mysql", "redis"}); err != nil {
		log.Fatal(err)
	}
	defer lib.Destroy()

	mysqlDo()

	redisDo()

	time.Sleep(time.Second)
}

type Test1 struct {
	Id        int64     `json:"id" gorm:"primary_key"`
	Name      string    `json:"name"`
	CreatedAt time.Time `json:"created_at"`
}

var (
	createTableSQL = "CREATE TABLE `test1` (`id` int(12) unsigned NOT NULL AUTO_INCREMENT" +
		" COMMENT '自增id',`name` varchar(255) NOT NULL DEFAULT '' COMMENT '姓名'," +
		"`created_at` datetime NOT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB " +
		"DEFAULT CHARSET=utf8"
	insertSQL    = "INSERT INTO `test1` (`id`, `name`, `created_at`) VALUES (NULL, '111', '2018-08-29 11:01:43');"
	dropTableSQL = "DROP TABLE `test1`"
	beginSQL     = "start transaction;"
	commitSQL    = "commit;"
	rollbackSQL  = "rollback;"
)

func NameEqual(name string) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		return db.Where("name = ?", name)
	}
}

func mysqlDo() {
	//获取链接池
	dbpool, err := lib.GetGormPool("default")
	if err != nil {

	}
	db := dbpool.Begin()

	traceCtx := lib.NewTraceContext()
	db = db.WithContext(traceCtx)
	//删除表数据
	if err := db.Exec(dropTableSQL).Error; err != nil {
	}

	if err := db.Exec(createTableSQL).Error; err != nil {
		db.Rollback()
	}

	//插入数据
	t1 := &Test1{Name: "test_name", CreatedAt: time.Now()}
	if err := db.Save(t1).Error; err != nil {
		db.Rollback()
	}

	//查询数据
	list := []Test1{}
	if err := db.Where("name=?", "test_name").Find(&list).Error; err != nil {
		db.Rollback()

	}
	fmt.Println(list)

	//使用预定义条件函数查询数据
	list1 := []Test1{}
	if err := db.Scopes(NameEqual("test_name")).Find(&list1).Error; err != nil {
		db.Rollback()

	}
	fmt.Println(list1)

	//删除表数据
	if err := db.Exec(dropTableSQL).Error; err != nil {
		db.Rollback()

	}
	db.Commit()
}

func redisDo() {
	rdb := lib.RedisConnFactory()

	err := rdb.Set(traceCtx, "key", "value", 0).Err()
	if err != nil {
		fmt.Println(err)
	}

	val, err := rdb.Get(traceCtx, "key1").Result()
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("key", val)

	val2, err := rdb.Get(traceCtx, "key2").Result()
	if err == redis.Nil {
		fmt.Println("key2 does not exist")
	} else if err != nil {
		panic(err)
	} else {
		fmt.Println("key2", val2)
	}

	// There is no error because go-redis automatically reconnects on error.
	pubsub := rdb.Subscribe(traceCtx, "mychannel1")
	ch := pubsub.Channel()
	go func() {
		for i := 0; i < 22; i++ {
			err = rdb.Publish(traceCtx, "mychannel1", "payload").Err()
			if err != nil {
				panic(err)
			}
			time.Sleep(time.Second)
		}
	}()

	for msg := range ch {
		fmt.Println(msg.Channel, msg.Payload)
	}
}
